<template>
    <Category :disabled="isShowList"/>
    <el-card shadow="always" :body-style="{ padding: '20px' }" :style="{marginTop: '30px'}">
        <template #header v-if="isShowList">
            <el-button type="primary" size="default" @click="addAttr" :icon="Plus" :disabled="!category3Id">添加属性</el-button>
        </template>
        <el-table  border stripe :data="attrList" v-if="isShowList">
            <el-table-column type="index" width="80" label="序号" />
            <el-table-column label="属性名称" width="150" prop="attrName"></el-table-column>
            <el-table-column label="属性名称">
                <template #="{row}">
                    <el-tag type="danger" size="default" effect="dark" v-for="item in row.attrValueList" 
                    :key="item.id" :style="{marginRight:'10px'}">
                    {{item.valueName}}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
                <template #="{row}">
                    <el-button type="warning" size="default" @click="updateAttr(row)" :icon="Edit"></el-button>
                    <el-popconfirm title="你确定要删除这个属性吗?" @confirm="deleteAttr(row)">
                        <template #reference>
                            <el-button type="danger" size="small" icon="ele-Delete"></el-button>
                        </template>
                    </el-popconfirm>
                </template> 
            </el-table-column>  
        </el-table>
        <div v-else>
            <el-form :inline="true" size="default">
                <el-form-item label="属性名">
                    <el-input placeholder="请输入属性名" v-model="newAttrData.attrName"></el-input>
                </el-form-item>
            </el-form>
            <div>
                <el-button type="primary" size="default" @click="addAttrValue" :disabled="!newAttrData.attrName">添加属性值</el-button>
                <el-button type="default" size="default" @click="cancel">取消</el-button>
            </div>
            <el-table  border stripe style="margin-top: 30px" :data="newAttrData.attrValueList">
                <el-table-column type="index" width="80" label="序号" />
                <el-table-column label="属性值名称">
                    <template #="{row,$index}">
                        <el-input v-model="row.valueName" placeholder="请输入属性值名称" v-if="row.isEdit"
                        ref="inpEle" @blur="changeToLook(row,$index)" @focus="saveOldValue(row)"
                        ></el-input>
                        <span :style="{display: 'inline-block', width: '70%'}" v-else @click="changeToEdit(row)">{{row.valueName}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="操作">
                    <template #="{$index}">
                        <el-popconfirm title="你确定要删除这个属性值吗?" @confirm="deleteAttrValue($index)">
                        <template #reference>
                            <el-button type="danger" size="small" icon="ele-Delete"></el-button>
                        </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <div style="margin-top: 30px">
                <el-button type="primary" size="default" @click="saveAttr" 
                :disabled="newAttrData.attrValueList.length <= 0 || !newAttrData.attrName"
                >保存</el-button>
                <el-button type="default" size="default" @click="cancel" >取消</el-button>
            </div>
        </div>
    </el-card>
    
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { ElMessage } from 'element-plus'

export default defineComponent({
    name: "Attr",
});
</script>

<script setup lang="ts">
    import {Plus,Delete,Edit} from '@element-plus/icons-vue'
    import {ref,watch,nextTick} from 'vue'
    import useAttrStore from '@/stores/attr'
    import {storeToRefs} from 'pinia'
    import {requestAttrInfo,requestUpdateOrAddAttr,requestDeleteAttr} from '@/api/attr'
    import type {reqAttrReturnType,reqAttrReturnItemType,reqAttrReturnAttrValueType} from '@/api/attr'
    import cloneDeep from 'lodash/cloneDeep'

    //创建attrList
    const attrList = ref<reqAttrReturnType>([])
    const attrStore = useAttrStore()
    const {category1Id,category2Id,category3Id} = storeToRefs(attrStore)
    
    //获取属性列表
    const getAttrList = async () => {
        const re = await requestAttrInfo(category1Id.value as number,category2Id.value as number,category3Id.value as number)
        attrList.value = re
    }
    //监听三级分类列表id,发送请求
    watch(category3Id,async (newValue) => {
        //点击一级分类时，清空了二级和三级分类
        if(!newValue){
            attrList.value = []
            return 
        } 
        //发送请求
        getAttrList()
    },{immediate:true})

    //控制属性列表显示与隐藏
    const isShowList = ref(true)

    //定义一个初始化新属性
    const newAttrData = ref<reqAttrReturnItemType>({
        attrName: '',
        categoryId: category3Id.value as number, //默认是category3Id
        categoryLevel: 3, //默认是3
        attrValueList: []
    })
    //点击添加属性
    const addAttr = () => {
        //清除修改属性残留
        newAttrData.value = {
            attrName: '',
            categoryId: category3Id.value as number, 
            categoryLevel: 3, 
            attrValueList: []
        }
        //显示添加属性页面
        isShowList.value = false
    }
    //点击添加属性值
    const addAttrValue = () => {
        //创建一个新的属性值
        const newAttrValue = ref<reqAttrReturnAttrValueType>({
            valueName:'',
            attrId: newAttrData.value.id,
            isEdit: true //控制属性值是否可编辑
        })
        //添加到attrValueList数组中
        newAttrData.value.attrValueList.push(newAttrValue.value)
        //添加属性值也需要自动获取焦点
        nextTick(() => {
            //自动获取焦点
            inpEle.value.focus()
        })
    }
    //点击修改
    const updateAttr = (row:reqAttrReturnItemType) => {
        //显示添加属性页面
        isShowList.value = false
        //数据双向绑定，把当前属性值赋值给newAttrData,需要深拷贝，因为对象地址一样，视图也会变
        const cloneData = cloneDeep(row)
        //遍历attrValueList给每一项添加isEdit,默认不可编辑
        cloneData.attrValueList.forEach(item => {
            item.isEdit = false
        })
        //赋值给newAttrData
        newAttrData.value = cloneData
    }
    //点击取消
    const cancel = () => {
        isShowList.value = true
    }
    //获取input元素
    const inpEle = ref()
    //点击变成可编辑
    const changeToEdit = (row:reqAttrReturnAttrValueType) => {
        row.isEdit = true
        //因为数据变了，页面还没更新，无法操作真实dom,需要nextTick
        nextTick(() => {
            //自动获取焦点
            inpEle.value.focus()
        })
    }   
    
    //定义一个旧值，每次编辑获取焦点时获取当前的旧值
    let oldValueName = ''
    //获取焦点事件
    const saveOldValue = (row:reqAttrReturnAttrValueType) => {
        oldValueName = row.valueName
    }
    //失去焦点，变成不可编辑
    const changeToLook = (row:reqAttrReturnAttrValueType,$index:number) => {
        row.isEdit = false
        //判断用户输入是否为空
        if(!row.valueName.trim()){
            //如果为空，判断是否有旧值
            if(oldValueName){
                //如果有，说明是修改属性,恢复旧值
                row.valueName = oldValueName
            }else{
                //如果没有，说明是新增属性，删除
                newAttrData.value.attrValueList.splice($index,1)
            }
        }
        //判断是否有重复值
        const isReset = newAttrData.value.attrValueList.some(item => {
            //自己不能和自己比较
            if(item === row){
                return
            }
            return item.valueName === row.valueName
        })

        //如果有重复值
        if(isReset){
            //判断是否有旧值
            if(oldValueName){
                //如果有，说明是修改属性,恢复旧值
                row.valueName = oldValueName
            }else{
                 //如果没有，说明是新增属性，删除
                 newAttrData.value.attrValueList.splice($index,1)
            }
        }
        //清空旧值，防止下次使用有问题
        oldValueName = ''
    }


    //点击删除属性值
    const deleteAttrValue = ($index:number) => {
        newAttrData.value.attrValueList.splice($index,1)
    }

    //点击保存，修改或者添加属性
    const saveAttr = async () => {
        //删除isEdit属性
        newAttrData.value.attrValueList.forEach(item => {
            delete item.isEdit
        })
        //判断属性值是否为空
        if(newAttrData.value.attrValueList.length <= 0){
            ElMessage.error('属性值不能为空')
            return
        }
        try {
            await requestUpdateOrAddAttr(newAttrData.value)
            ElMessage.success('修改或添加成功')
            //回到列表页
            isShowList.value = true
            //重新获取属性列表
            getAttrList()
        } catch (e) {
            ElMessage.error('修改或添加失败')
        }
    }

    //删除属性
    const deleteAttr = async (row:reqAttrReturnItemType) => {
        try {
            await requestDeleteAttr(row.id as number)
            ElMessage.success('删除成功')
            //重新获取属性列表
            getAttrList()
        } catch (e) {
            ElMessage.error('删除失败')
        }
    }
</script>